package air

import "sync"

type Router interface {
	Use(args ...MiddlewareFunc)
	On(e string, fn EventHandler)
	Handler(e string) EventHandler
	middlewares() []MiddlewareFunc
}

type MiddlewareFunc func(EventHandler) EventHandler

type Group struct {
	middleware []MiddlewareFunc
	server     *Server

	msgHandlers     map[string]EventHandler
	msgHandlersLock sync.RWMutex
}

func NewGroup(s *Server) *Group {
	g := &Group{
		middleware:  s.middleware,
		server:      s,
		msgHandlers: make(map[string]EventHandler),
	}
	return g
}

func (g *Group) On(e string, fn EventHandler) {
	switch e {
	case OnConnect, OnHeartbeat, OnJoin, OnLeave, OnDisconnect, OnClose:
		g.server.log.Error("group does not support reserved event")
	default:
		g.msgHandlersLock.Lock()
		defer g.msgHandlersLock.Unlock()
		g.msgHandlers[e] = fn
		g.server.SetRouter(e, g)
	}
}

func (g *Group) Handler(e string) EventHandler {
	g.msgHandlersLock.Lock()
	defer g.msgHandlersLock.Unlock()
	return g.msgHandlers[e]
}

func (g *Group) Use(middleware ...MiddlewareFunc) {
	g.middleware = append(g.middleware, middleware...)
}

func (g *Group) Group(middleware ...MiddlewareFunc) (sg *Group) {
	m := make([]MiddlewareFunc, 0, len(g.middleware)+len(middleware))
	m = append(m, g.middleware...)
	m = append(m, middleware...)
	sg = g.server.Group(m...)
	return
}

func (g *Group) middlewares() []MiddlewareFunc {
	return g.middleware
}

func applyMiddleware(h EventHandler, middleware ...MiddlewareFunc) EventHandler {
	for i := len(middleware) - 1; i >= 0; i-- {
		h = middleware[i](h)
	}
	return h
}
